package common.files.xml.xsd;

import java.util.Iterator;
import java.util.LinkedHashSet;

import org.dom4j.Element;

import common.utils.StringHelper;

public class NodeXsd {
	protected String name;
	protected LinkedHashSet<ElementXsd> children;
	protected LinkedHashSet<AttributeXsd> attributes;
	protected ElementXsd parent;
	protected boolean isRoot = true;

	public NodeXsd() {
		children = new LinkedHashSet<ElementXsd>();
		attributes = new LinkedHashSet<AttributeXsd>();
	}

	public NodeXsd(String name) {
		this();
		this.name = name;
	}

	public NodeXsd(Element element) {
		this.name = element.getName();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public ElementXsd getParent() {
		return parent;
	}

	public void setParent(ElementXsd parent) {
		this.parent = parent;
		this.isRoot = false;
	}

	public LinkedHashSet<ElementXsd> getChildren() {
		return children;
	}

	public void setChildren(LinkedHashSet<ElementXsd> children) {
		this.children = children;
	}

	public void addChild(ElementXsd child) {
		this.children.add(child);
	}

	public LinkedHashSet<AttributeXsd> getAttributes() {
		return attributes;
	}

	public void setAttributes(LinkedHashSet<AttributeXsd> attributes) {
		this.attributes = attributes;
	}

	public void addAttribute(AttributeXsd attribute) {
		this.attributes.add(attribute);
	}

	public boolean isRoot() {
		return isRoot;
	}

	@Override
	public String toString() {
		if (StringHelper.isEmpty(this.name)) {
			return "";
		}
		StringBuffer sb_result = new StringBuffer();
		sb_result.append("<" + this.name + ">");
		if (!this.children.isEmpty()) {
			Iterator<ElementXsd> ite = this.children.iterator();
			while (ite.hasNext()) {
				sb_result.append(ite.next().toString());
			}
		}
		sb_result.append("</" + this.name + ">");

		return sb_result.toString();
	}

	public boolean eaquals(NodeXsd target) {
		boolean eaquals = true;
		if (!this.name.equalsIgnoreCase(target.getName())) {
			return eaquals = false;
		}
		if (this.parent != null && !this.parent.eaquals(target)) {
			return eaquals = false;
		}
		if (!this.children.isEmpty()) {
			Iterator<ElementXsd> ite = this.children.iterator();
			while(ite.hasNext()){
				if(ite.next() != null && !ite.next().eaquals(target)){
					return eaquals = false;
				}
			}
		}

		return eaquals;
	}
	
	public boolean existChild(ElementXsd target){
		boolean exists = false;
		if(this.children.isEmpty()){
			return exists = false;
		}
		
		Iterator<ElementXsd> ite = this.children.iterator();
		while(ite.hasNext()){
			if(ite.next().exists(target))
				return exists = true;
		}
		
		return exists;
	}
	
	public boolean hasUpdatedChild(ElementXsd target){
		boolean hasUpdatedChild = false;
		if(!this.existChild(target)){
			return hasUpdatedChild = false;
		}
		
		Iterator<ElementXsd> ite = this.children.iterator();
		ElementXsd child;
		while(ite.hasNext()){
			child = ite.next();
			if(child != null && child.isSame(target)){
				return hasUpdatedChild = !child.eaquals(target);
			}
		}
		
		return hasUpdatedChild;
	}
	
	public void updateChild(ElementXsd target){
		// TODO update the exists child
		if(!this.existChild(target)){
			return;
		}
		
		Iterator<ElementXsd> ite = this.children.iterator();
		ElementXsd child;
		while(ite.hasNext()){
			child = ite.next();
			if(child != null && child.isSame(target)){
				child.updateElememtXsd(target);
			}
		}
	}
	
	public boolean isSame(NodeXsd target){
		if(this.name.equalsIgnoreCase(target.name)){
			return true;
		}else{
			return false;
		}
	}
}
